
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Swaf.Security;

/// <summary>
/// Summary description for ActionButton
/// </summary>
/// 
namespace Swaf.Gui.AspNet2
{
	[ToolboxData("<{0}:ActionButton runat=server></{0}:ActionButton>")]
	public class ActionButton : Button, IActionTrigger
	{
		protected static string s_popupScript = @"if(window.showModalDialog(""{0}?T={3}"",null,""dialogWidth:{1}; dialogHeight:{2}; center:yes; resizable: yes; help: no "")==true){{{4}}}else return false;";
		protected static string s_olderFireFoxPopupScript =
			@"var rv = {{r:null}};openDialog('{0}?T={3}','dlg','modal,resizable=yes,width={1},height{2}',rv);if(rv.r == true){{{4}}}";
		protected string m_popupWidth = "350px";
		protected string m_popupHeight = "200px";
		protected string m_popupTitle = "Action Parameters";

		protected string m_clientScript = null;
		protected string m_afterClientScript = null;
		protected bool m_hideOnDisabled = true;
		protected string m_bizprocActions = null;
		protected string m_sessionBoolSwitch = null;
		protected string m_popupPage = null;
		protected bool m_createActiveOnLoad = true;
		protected string m_specifiedTriggerParam = null;
		protected BizProcWidgetType m_procType = BizProcWidgetType.button;
		protected bool m_canceledTrigger = false;

		public ActionButton()
		{
			this.Click += new EventHandler(ActionButton_Click);
		}

		public ActionButton(ActiveWidget widget)
		{
			ID = widget.State.Id;
		}

		protected override void OnLoad(EventArgs e)
		{
			WidgetOfflineState offlineState = State;
			if (m_createActiveOnLoad)
			{
				//if (!BPC.ActiveWidgets.ContainsKey(offlineState.Id))
			//	{
					ActiveWidget act = new ActiveWidget(this, BPC, offlineState);
					act.CreatedFromPage = false;
					BPC.defineActiveWidget(act);
			//	}
			}
			base.OnLoad(e);
		}

		public virtual string ClientClick { get { return m_clientScript; } set { m_clientScript = value; } }
		public virtual string AfterClientClick { get { return m_afterClientScript; } set { m_afterClientScript = value; } }
		
		public bool HideOnDisabled
		{
			get { return (bool)State.State.get("hideOnDisable"); }
			set { m_hideOnDisabled = value; }
		}

		public string Actions
		{
			get { string s = (string)State.State.get("actions"); return s == null ? m_bizprocActions : s; }
			set { m_bizprocActions = value; if (BPC != null)State.State.put("actions", value); }
		}

		public string SessionBoolSwitch
		{
			get { return (string)State.State.get("boolSwitch"); }
			set { m_sessionBoolSwitch = value; }
		}
		public string PopupPage
		{
			get { return (string)State.State.get("popupPage"); }
			set { m_popupPage = value; }
		}
		public string PopupWidth { get { return (string)getOffline("m_popupWidth"); } set { putOffline("m_popupWidth",value); } }
		public string PopupHeight { get { return (string)getOffline("m_popupHeight"); } set { putOffline("m_popupHeight", value); } }
		public string PopupTitle { get { return (string)getOffline("m_popupTitle"); } set { putOffline("m_popupTitle", value); } }
		public string TriggerParam { get { return (string)getOffline("m_specifiedTriggerParam"); } set { putOffline("m_specifiedTriggerParam", value); } }

		void ActionButton_Click(object sender, EventArgs e)
		{
			OnClick();
		}

		protected virtual void OnClick()
		{
			if (SessionBoolSwitch != null)
			{
				IDictionary sd = Application.currentApp.sessionData;
				if (sd[SessionBoolSwitch] is bool)
					sd[SessionBoolSwitch] = !(bool)sd[SessionBoolSwitch];
				else
					sd[SessionBoolSwitch] = true;
			}

			object popupTrigParam = TriggerParam;
			if (PopupPage != null)
			{
				popupTrigParam = Application.currentApp.sessionData["AjaxPopupActionState"];
				Application.currentApp.sessionData["AjaxPopupActionState"] = null;
			}
			string[] actionNames = Actions.Split(',');
			foreach (string actionName in actionNames)
			{
				object trigParam = null;
				IAction action = BPC.getBizProcAction(actionName, ref trigParam);
				if (popupTrigParam != null && trigParam == null)
					trigParam = popupTrigParam;
				if (action != null && action.Enabled)
					if (Page == null || (PopupPage == null && trigParam == null))
					{
						if ((m_canceledTrigger = !action.trigger()) == true)
							break;
					}
					else
						action.trigger(trigParam);
			}
		}

		protected virtual IAction getActionForAvailability()
		{
			List<IAction> actions = BPC.getBizProcActions(Actions);
			IAction action = null;
			if (actions != null && actions.Count > 0)
			{
				action = actions[0];
				//HACK: This check for a specific action called VerifyUser is a hack to help
				//avoid a new situation where a verifyuser action is put in at the begining just
				//so that it can cancel the action if the user wasnt verified.  We still want
				//overall action availability to come from the next action, which is the real
				//first action
				if (action.Id.CompareTo("VerifyUser") == 0 && actions.Count > 1)
					action = actions[1];
			}
			return action;
		}

		protected override void OnPreRender(EventArgs e)
		{

			if (!m_canceledTrigger)
			{
				IAction availAction = getActionForAvailability();
				ActionAvailability av = ActionAvailability.none;
				if(availAction != null)
					av = availAction.Availability;

				if (av == ActionAvailability.disabled)
					this.Enabled = false;
				else if (av == ActionAvailability.none)
					this.Visible = false;
				else
				{
					this.Enabled = true;
					this.Visible = true;
				}
				string clientClick = ClientClick;
				if (PopupPage != null)
				{
					//if(Page.Request.Browser.Browser.ToUpper().IndexOf("IE") != -1)
					clientClick = string.Format(s_popupScript, m_popupPage, m_popupWidth, m_popupHeight, m_popupTitle, clientClick);
					//else
					//	clientClick = string.Format(s_olderFireFoxPopupScript, m_popupPage, m_popupWidth, m_popupHeight, m_popupTitle, clientClick.Replace('\"','\''));
				}
				if (clientClick != null)
					base.Attributes.Add("onclick", Swaf.Application.currentApp.resMgr.resolve(clientClick));
			}

			base.OnPreRender(e);
		}

		protected WidgetOfflineState State
		{
			get
			{
				WidgetOfflineState state = BPC.getWidgetOfflineState(WidgetId);
				if (state == null)
				{
					BPC.addWidgetOfflineState(state = new WidgetOfflineState(WidgetId, this.GetType().AssemblyQualifiedName));
					state.BizProcWidgetType = BizProcWidgetType;
					if (state.State.get("boolSwitch") == null)
					{
						state.State.put("boolSwitch", m_sessionBoolSwitch);
						state.State.put("hideOnDisable", m_hideOnDisabled);
						if(m_popupPage != null)
							state.State.put("popupPage", m_popupPage);
						state.State.put("m_popupWidth", m_popupWidth);
						state.State.put("m_popupHeight", m_popupHeight);
						state.State.put("m_popupTitle", m_popupTitle);
						state.State.put("actions", Actions);
						if(m_specifiedTriggerParam != null)
							state.State.put("m_specifiedTriggerParam", m_specifiedTriggerParam);
					}
					setupParentBizProcs();
				}
				return state;
			}
		}

		protected void setupParentBizProcs()
		{
			if (m_bizprocActions != null)
			{
				State.ParentBizProcIds.Clear();
				string[] bizprocids = m_bizprocActions.Split(',');
				foreach (string bizprocid in bizprocids)
				{
					string[] actionInfo = bizprocid.Split('.');
					if (actionInfo.Length == 2)
						State.ParentBizProcIds.Add(actionInfo[0]);
					else
						throw new BaseException(string.Format("Invalid ActionButton.Actions property format: {0}", m_bizprocActions));
				}
			}
		}

		public BizProcCoordinator BPC
		{
			get { return (Page is IPage) ? ((IPage)Page).BPC : null; }
		}

		public string WidgetId {get { return ClientID; }}
		public string ParentBizProcIds{get{return Actions;}set{Actions = value;}}
		public BizProcWidgetType BizProcWidgetType {get{return m_procType;}set{m_procType = value;}}
		protected void putOffline(string keyName, object val)
		{
			if (BPC != null)
				State.State.put(keyName, val);
			Cmn.callPropertySet(this, keyName, val);
		}
		protected object getOffline(string keyName)
		{
			object v = BPC == null ? null : State.State.get(keyName);
			if (v == null)
				v = Cmn.callPropertyGet(this, keyName);
			return v;
		}
	}
}
